/**
 * 用户控制器
 * 提供用户会话的创建、查询、更新和删除功能
 * 支持分页查询和搜索功能，包含完整的错误处理机制
 */
import { Elysia, t } from 'elysia';

import { userService } from '@/services/user';
import { ApiError } from '@/types';

/**
 * 用户数据模式定义
 * 定义用户对象的结构，用于API响应中的数据格式
 */
const UserSchema = t.Object(
  {
    id: t.String({
      description: '用户唯一标识符',
      example: 'user_abc123def456',
    }),
    name: t.String({
      description: '用户姓名',
      example: 'John Doe',
    }),
    email: t.String({
      description: '用户邮箱地址',
      format: 'email',
      example: 'john.doe@example.com',
    }),
    createdAt: t.Date({
      description: '用户创建时间戳',
      example: '2024-01-01T00:00:00.000Z',
    }),
    updatedAt: t.Date({
      description: '用户最后更新时间戳',
      example: '2024-01-01T00:00:00.000Z',
    }),
  },
  {
    description: '用户基本信息',
  }
);

/**
 * 用户控制器
 * 提供用户相关的 API 端点，包括用户管理和查询功能
 */
export const userController = new Elysia({ prefix: '/users' })
  // 获取用户列表
  .get(
    '/',
    async ({ query }) => {
      const page = parseInt(query.page ?? '1', 10);
      const limit = parseInt(query.limit ?? '10', 10); // 参数验证
      if (page < 1) {
        throw new ApiError(400, '页码必须大于0');
      }

      if (limit < 1 || limit > 100) {
        throw new ApiError(400, '每页数量必须在1-100之间');
      }

      return await userService.getUsers(page, limit);
    },
    {
      query: t.Object({
        page: t.Optional(
          t.String({
            description: '页码，从1开始',
            examples: ['1', '2'],
          })
        ),
        limit: t.Optional(
          t.String({
            description: '每页数据量，范围1-100',
            examples: ['10', '20'],
          })
        ),
      }),
      detail: {
        summary: '获取用户列表',
        description: '获取分页的用户列表',
        tags: ['用户'],
      },
      response: {
        200: t.Array(UserSchema, {
          description: '用户列表',
        }),
        400: t.String({
          description: '参数错误',
          example: '页码必须大于0',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  )
  // 根据ID获取用户
  .get(
    '/:id',
    async ({ params }) => {
      return await userService.getUserById(params.id);
    },
    {
      params: t.Object({
        id: t.String({
          description: '用户ID',
          example: '1',
        }),
      }),
      detail: {
        summary: '获取用户详情',
        description: '根据用户ID获取用户的详细信息',
        tags: ['用户'],
      },
      response: {
        200: UserSchema,
        400: t.String({
          description: '参数错误',
          example: '用户ID不能为空',
        }),
        404: t.String({
          description: '用户未找到',
          example: '用户不存在或已被删除',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  )
  // 创建用户
  .post(
    '/',
    async ({ body }) => {
      return await userService.createUser(body);
    },
    {
      body: t.Object({
        name: t.String({
          description: '用户姓名',
          minLength: 1,
          maxLength: 100,
          example: 'Alice Johnson',
        }),
        email: t.String({
          description: '用户邮箱地址',
          format: 'email',
          example: 'alice@example.com',
        }),
      }),
      detail: {
        summary: '创建用户',
        description: '创建新用户，需要提供姓名和邮箱',
        tags: ['用户'],
      },
      response: {
        201: UserSchema,
        400: t.String({
          description: '参数错误',
          example: '邮箱格式无效或已存在',
        }),
        409: t.String({
          description: '冲突错误',
          example: '邮箱已存在',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  )
  // 更新用户
  .put(
    '/:id',
    async ({ params, body }) => {
      return await userService.updateUser(params.id, body);
    },
    {
      params: t.Object({
        id: t.String({
          description: '用户ID',
          example: '1',
        }),
      }),
      body: t.Object({
        name: t.Optional(
          t.String({
            description: '用户姓名',
            minLength: 1,
            maxLength: 100,
            example: 'John Smith',
          })
        ),
        email: t.Optional(
          t.String({
            description: '用户邮箱地址',
            format: 'email',
            example: 'john.smith@example.com',
          })
        ),
      }),
      detail: {
        summary: '更新用户',
        description: '更新用户信息，支持部分更新',
        tags: ['用户'],
      },
      response: {
        200: UserSchema,
        400: t.String({
          description: '参数错误',
          example: '用户ID不能为空或邮箱格式无效',
        }),
        404: t.String({
          description: '用户未找到',
          example: '用户不存在或已被删除',
        }),
        409: t.String({
          description: '冲突错误',
          example: '邮箱已存在',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  )
  // 删除用户
  .delete(
    '/:id',
    async ({ params }) => {
      await userService.deleteUser(params.id);
      return { message: '用户删除成功' };
    },
    {
      params: t.Object({
        id: t.String({
          description: '用户ID',
          example: '1',
        }),
      }),
      detail: {
        summary: '删除用户',
        description: '根据用户ID删除用户',
        tags: ['用户'],
      },
      response: {
        200: t.Object(
          {
            message: t.String({
              description: '操作结果消息',
              examples: ['用户删除成功'],
            }),
          },
          {
            description: '用户删除成功消息',
          }
        ),
        400: t.String({
          description: '参数错误',
          example: '用户ID不能为空',
        }),
        404: t.String({
          description: '用户未找到',
          example: '用户不存在或已被删除',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  )
  // 搜索用户
  .get(
    '/search',
    async ({ query }) => {
      const page = parseInt(query.page ?? '1', 10);
      const limit = parseInt(query.limit ?? '10', 10); // 参数验证
      if (!query.q || query.q.trim().length === 0) {
        throw new ApiError(400, '搜索关键词不能为空');
      }

      if (page < 1) {
        throw new ApiError(400, '页码必须大于0');
      }

      if (limit < 1 || limit > 100) {
        throw new ApiError(400, '每页数量必须在1-100之间');
      }

      return await userService.searchUsers(query.q, page, limit);
    },
    {
      query: t.Object({
        q: t.String({
          description: '搜索关键词',
          minLength: 1,
          example: 'john',
        }),
        page: t.Optional(
          t.String({
            description: '页码，从1开始',
            examples: ['1', '2'],
          })
        ),
        limit: t.Optional(
          t.String({
            description: '每页数据量，范围1-100',
            examples: ['10', '20'],
          })
        ),
      }),
      detail: {
        summary: '搜索用户',
        description: '根据姓名或邮箱搜索用户',
        tags: ['用户'],
      },
      response: {
        200: t.Array(UserSchema, {
          description: '匹配的用户列表',
        }),
        400: t.String({
          description: '参数错误',
          example: '搜索关键词不能为空',
        }),
        500: t.String({
          description: '服务器内部错误',
          example: '服务器发生错误，请稍后再试',
        }),
      },
    }
  );
